#pragma once

namespace ParaEngine
{
	/** Biped way point: see CBipedObject::m_vPosTarget */
	struct BipedWayPoint
	{
	public:

		enum MyType {
			/// the player must arrive at this point, before proceeding to the next way point
			/// when in this mode, player are moving while turning, if the angle is smaller then 90
			/// degrees, otherwise the player will first turn until the angle shift is smaller than 
			/// 90 degrees, and then move while turning.
			COMMAND_POINT = 0,
			/// turning 
			COMMAND_FACING,
			/// Move the biped forward using its current orientation. It is mutually exclusive with other 
			/// walking or way point commands. The command will always be in the way point list until it is
			/// either cleared or overridden by some other commands.
			COMMAND_WALK_FORWARD,
			COMMAND_MOVING,
			/** character is mounted on another object. */
			COMMAND_MOUNT,
			/// when player is blocked, it may itself generate some path-finding points in 
			/// order to reach the next COMMAND_POINT. When in this mode, player are first 
			/// turned and then move. 
			PATHFINDING_POINT,
			/// The player is blocked, and needs to wait fTimeLeft (see below) in order to proceed.
			/// it may continue to be blocked, or walk along. Player in blocked state, does not have
			/// a speed, so it can issue attacks while in blocked mode. 
			BLOCKED,
			/// the following way points are cognitive way points, which means that they are subjective
			/// either generated by an AI module or an external user. COGNITIVE way point can not be
			/// executed immediately, instead they must be converted to one of the previous way points
			/// by the environment simulator. 
			COGNITIVE,
			/// the biped intends to move to a new position
			COGNITIVE_POINT,
			/// the biped intends to face to a new direction
			COGNITIVE_FACING,
			/// Invalid way point
			INVALID_WAYPOINT
		} nType;


		DVector3  vPos;
		/// in seconds; Way point is deleted after fTimeLeft seconds.
		/// if negative, then the position is persistent, until being reached.
		float		 fTimeLeft;
		float		 fFacing;
		bool		 bUseFacing : 1;
		int			m_nReserved0;
		/// this is usually the mount target object's name. 
		string		 m_sTarget;

	public:
		MyType GetPointType(){ return nType; }
		void SetPointType(MyType newType){ nType = newType; }
		/** return true, if the point type is of a moving kind. i.e. value < BLOCKED */
		bool IsMoving();
		/** whether facing should be enforced.*/
		bool IsUseFacing();
		const DVector3& GetPosition() const { return vPos; };

		BipedWayPoint(const Vector3& p, MyType ptType = COMMAND_POINT, float fTime = -1.0f);
		BipedWayPoint(const Vector3& p, float facing, MyType ptType = COMMAND_POINT, float fTime = -1.0f);
		BipedWayPoint(float fBlockTime);
		BipedWayPoint(MyType ptType);
		BipedWayPoint();
	};
}